const canvas = document.createElement("canvas");
canvas.width = 600;
canvas.height = 400;
canvas.style.position = "fixed";
canvas.style.bottom = "8px";
canvas.style.right = "8px";
canvas.style.zIndex = "1";
document.body.appendChild(canvas);

// const canvas = document.getElementById("canvas");
const ctx2d = canvas.getContext("2d");
let drawable = false;

// const observer = new ResizeObserver((e) => {
//   const { width, height } = e[0].contentRect;
//   canvas.width = width;
//   canvas.height = height;

//   initCtx(ctx2d);
// });
// observer.observe(document.body);

const initCtx = (ctx) => {
  if (ctx) {
    ctx.translate(canvas.width / 2, canvas.height / 2);
    ctx.scale(1, -1);
    drawable = true;
  }
};

initCtx(ctx2d);

const drawAxis = (ctx) => {
  if (ctx) {
    ctx.clearRect(
      -canvas.width / 2,
      -canvas.height / 2,
      canvas.width,
      canvas.height
    );

    ctx.beginPath();
    ctx.strokeStyle = "#FfFfFf20";
    ctx.lineWidth = 1;
    ctx.moveTo(0, 0);
    ctx.lineTo(canvas.width / 2 - 10, 0);
    ctx.moveTo(0, 0);
    ctx.lineTo(0, canvas.height / 2 - 10);
    ctx.moveTo(0, 0);
    ctx.lineTo(-canvas.width / 2 + 10, 0);
    ctx.moveTo(0, 0);
    ctx.lineTo(0, -canvas.height / 2 + 10);
    ctx.stroke();
  }
};

const points = [];
const pssine = [];
const draw = (ctx, idx = 0) => {
  if (ctx) {
    let x = 0;
    let y = 0;
    circles.forEach((c) => {
      drawCircle(ctx, x, y, c);
      const st = { x, y };
      x += c.r * Math.cos((c.ω * idx * Math.PI) / 180);
      y += c.r * Math.sin((c.ω * idx * Math.PI) / 180);
      const sp = { x, y };
      drawVector(ctx, st, sp);
    });

    points.push(x);
    points.push(y);
    if (points.length > canvas.height * canvas.width * 2) {
      points.shift();
      points.shift();
    }
    drawSolve(ctx, points);

    pssine.unshift(y);
    if (pssine.length > canvas.height * canvas.width) {
      pssine.pop();
    }
    const pp = [];
    pssine.forEach((p, i) => {
      pp.push(i / 2 + 200);
      pp.push(p);
    });
    drawSolve(ctx, pp, null, "#0000ff");

    drawLink(ctx, { x, y }, { x: 200, y });
  }
};

const drawCircle = (ctx, x, y, c) => {
  ctx.strokeStyle = "#Ff0000";
  ctx.beginPath();
  ctx.arc(x, y, c.r, 0, 2 * Math.PI);
  ctx.stroke();
};

const theta = (20 * Math.PI) / 180;
const lllll = 10;
const drawVector = (ctx, st, sp) => {
  ctx.strokeStyle = "#Ff00ff";
  ctx.beginPath();
  ctx.moveTo(st.x, st.y);
  ctx.lineTo(sp.x, sp.y);
  const alpha = Math.atan2(sp.y - st.y, sp.x - st.x);
  const phi1 = Math.PI / 2 - alpha - theta;
  const phi2 = alpha - theta;
  const p1 = {
    x: sp.x - lllll * Math.sin(phi1),
    y: sp.y - lllll * Math.cos(phi1),
  };
  const p2 = {
    x: sp.x - lllll * Math.cos(phi2),
    y: sp.y - lllll * Math.sin(phi2),
  };
  ctx.moveTo(sp.x, sp.y);
  ctx.lineTo(p1.x, p1.y);
  ctx.moveTo(sp.x, sp.y);
  ctx.lineTo(p2.x, p2.y);
  ctx.stroke();

  // ctx.strokeStyle = "#Ff00ff00";
  // ctx.fillStyle = "#Ff00ff";
  // ctx.beginPath();
  // ctx.arc(sp.x, sp.y, 3, 0, 2 * Math.PI);
  // ctx.fill();
  // ctx.stroke();
};

function drawSolve(ctx, data, k = null, color = null) {
  if (k === null) k = 1;
  var size = data.length;
  var last = size - 4;
  ctx.strokeStyle = color || "#Fff0f0";
  ctx.beginPath();
  ctx.moveTo(data[0], data[1]);
  for (var i = 0; i < size - 2; i += 2) {
    var x0 = i ? data[i - 2] : data[0];
    var y0 = i ? data[i - 1] : data[1];
    var x1 = data[i + 0];
    var y1 = data[i + 1];
    var x2 = data[i + 2];
    var y2 = data[i + 3];
    var x3 = i !== last ? data[i + 4] : x2;
    var y3 = i !== last ? data[i + 5] : y2;
    var cp1x = x1 + ((x2 - x0) / 6) * k;
    var cp1y = y1 + ((y2 - y0) / 6) * k;
    var cp2x = x2 - ((x3 - x1) / 6) * k;
    var cp2y = y2 - ((y3 - y1) / 6) * k;
    ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x2, y2);
  }
  ctx.stroke();
}

function drawLink(ctx, p1, p2) {
  ctx.beginPath();
  ctx.strokeStyle = "#Ffff00";
  ctx.setLineDash([5, 5]);
  ctx.moveTo(p1.x, p1.y);
  ctx.lineTo(p2.x, p2.y);
  ctx.stroke();
  ctx.setLineDash([]);
}

// const circles = [
//   { r: 100, ω: 1, φ: 0 },
//   { r: 100 / 3, ω: 3, φ: 0 },
//   { r: 100 / 5, ω: 5, φ: 0 },
//   { r: 100 / 7, ω: 7, φ: 0 },
//   { r: 100 / 9, ω: 9, φ: 0 },
// ];

const getCircles = (N = 10) => {
  const ret = [];
  for (let i = 0; i < N; i += 1) {
    ret.push({ r: 100 / (i * 2 + 1), ω: i * 2 + 1, φ: 0 });
  }
  return ret;
};
const circles = getCircles(30);

let i = 0;
(function run() {
  if (drawable) {
    drawAxis(ctx2d);
    draw(ctx2d, i);
    i += 1;
  }
  return requestAnimationFrame(run);
})();
